package me.zk;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.maxBy;
import static java.util.stream.Collectors.partitioningBy;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;

/**
 * @Author: zhang kai
 * @Date: 2022/07/12
 * @Description:
 */
public class Demo5 {
    public static void main(String[] args) {
        List<Dish> menu = Arrays.asList(
                new Dish("pork", false, 800, Dish.Type.MEAT),
                new Dish("beef", false, 700, Dish.Type.MEAT),
                new Dish("chicken", false, 400, Dish.Type.MEAT),
                new Dish("french fries", true, 530, Dish.Type.OTHER),
                new Dish("rice", true, 350, Dish.Type.OTHER),
                new Dish("season fruit", true, 120, Dish.Type.OTHER),
                new Dish("pizza", true, 550, Dish.Type.OTHER),
                new Dish("prawns", false, 300, Dish.Type.FISH),
                new Dish("salmon", false, 450, Dish.Type.FISH) );

        List<Dish> vegetarianMenu  = menu.stream().filter(Dish::isVegetarian).collect(toList());

        List<Dish> dishes1 = menu.stream().filter(d -> d.getCalories() > 300).limit(3).collect(toList());

        List<Dish> dishes2 = menu.stream()
                .filter(d -> d.getCalories() > 300)
                .skip(2)
                .collect(toList());
        List<String> dishNames = menu.stream()
                .map(Dish::getName)
                .collect(toList());

        boolean isHealthy = menu.stream()
                .allMatch(d -> d.getCalories() < 1000);
        Optional<Dish> dish =
                menu.stream()
                        .filter(Dish::isVegetarian)
                        .findAny();
        System.out.println(dish.get().getName());

        int total = menu.stream().map(Dish::getCalories).reduce(0, Integer::sum);
        System.out.println(total);
        Optional<Integer> max = menu.stream().map(Dish::getCalories).reduce(Integer::max);
        List<String> title = Arrays.asList("Java8", "In", "Action");
        List<String> l = title.stream()
                .map(word -> word.split(""))
                .flatMap(Arrays::stream)
                .distinct()
                .collect(toList());
        String shortMenu = menu.stream().map(Dish::getName).collect(joining(","));
        System.out.println(shortMenu);

        Map<Dish.Type,List<Dish>> map =  menu.stream().collect(groupingBy(Dish::getType));
        System.out.println(map);
        Map<Dish.Type, Map<Dish.CaloricLevel, List<Dish>>> dishesByTypeCaloricLevel =
                menu.stream().collect(groupingBy(Dish::getType,groupingBy(d -> {
                    if (d.getCalories() <= 400) return Dish.CaloricLevel.DIET;
                    else if (d.getCalories() <=700) return Dish.CaloricLevel.NORMAL;
                    else return Dish.CaloricLevel.FAT;
                })));
        System.out.println(dishesByTypeCaloricLevel);
        Map<Boolean, List<Dish>> partitionedMenu =
                menu.stream().collect(partitioningBy(Dish::isVegetarian));


    }
    public static long parallelSum(long n) {
        return Stream.iterate(1L, i -> i + 1)
                .limit(n)
                .parallel()
                .reduce(0L, Long::sum);
    }
}
